
//Copyright 1997-2009 Syrinx Development, Inc.
//This file is part of the Syrinx Web Application Framework (SWAF).
// == BEGIN LICENSE ==
//
// Licensed under the terms of any of the following licenses at your
// choice:
//
//  - GNU General Public License Version 3 or later (the "GPL")
//    http://www.gnu.org/licenses/gpl.html
//
//  - GNU Lesser General Public License Version 3 or later (the "LGPL")
//    http://www.gnu.org/licenses/lgpl.html
//
//  - Mozilla Public License Version 1.1 or later (the "MPL")
//    http://www.mozilla.org/MPL/MPL-1.1.html
//
// == END LICENSE ==
using System;
using System.IO;
using System.Xml;
using System.Text;
using System.Text.RegularExpressions;
using Swaf.BizObj;

namespace Swaf.BizObj.xml
{
	/// <summary> Implements the <c>IBizObjCursor</c> interface by using a 
	/// <c>IListState</c> that maintains an XML xpath query into a given XML
	/// element as its data store.
	/// *
	/// </summary>
	/// <author>  mdenman
	/// 
	/// </author>
	[Serializable]
	public class XmlBusinessObjectList : BaseBizObjList, IXmlNodeParent
	{
		private ListState m_state;
		private int m_listPos;
		private XmlDependentBizObj m_bizobj;

		/// <summary>Creates a new instance of XmlBusinessObjectIList 
		/// </summary>
		public XmlBusinessObjectList(IBizObjDefinition objType, ListState state)
			:this(objType, state, null)
		{
			//Intentionally left blank.
		}

		/// <summary>Creates a new instance of XmlBusinessObjectIList 
		/// </summary>
		public XmlBusinessObjectList(IBizObjDefinition objType, ListState state, IBizObjSource source)
			:base(source)
		{
			m_listPos = 0;
			m_state = state;
			m_bizobj = new XmlDependentBizObj(objType, this);
		}

		
		public override IBizObjDefinition objectType
		{get{
			 return m_bizobj.type;
		}}

		public override int numElements
		{get{
			 if(m_state != null && m_state.list != null)
				return m_state.list.Count;
			 else 
				 return 0;
		}}

		public override IBizObj search(string fieldList, object matchValue)
		{
			return search(fieldList,matchValue,false);
		}
		public override IBizObj search(string fieldList, object matchValue, bool findNearestMatch)
		{
			//TODO: Implement this.
			return null;
		}

		
		public XmlElement getChildElement(string name, bool createIfNeeded)
		{
			//Name is irrelivatent to the list, which just returns the current element
			return currentXmlElement;
		}
		protected XmlElement currentXmlElement
		{get{
			int numEl = numElements;
			if (numEl > 0 && m_listPos >= 0 && m_listPos < numEl)
				return (XmlElement)m_state.list[m_listPos];
			else
				return null;
		}}
		
		
		public override string Xml
		{get{
			return getXml("public");
		}}


		public override string getXml(string name, bool setOnly, bool dirtyOnly, bool newOnly, bool getBasic, bool getObjs, bool getILists, bool getSysVals, XmlTextWriter xmlOut)
		{
			return getXml(name, BaseBizObj.DefaultFieldDecoInfo, setOnly, dirtyOnly, newOnly, getBasic, getObjs, getILists, getSysVals, xmlOut);
		}
		public override string getXml(string name, string decoInfo, bool setOnly, bool dirtyOnly, bool newOnly, bool getBasic, bool getObjs, bool getILists, bool getSysVals, XmlTextWriter xmlOut)
		{
			StringWriter strBuf = null;
			bool madeXmlOut = false;
			if(xmlOut == null)
			{
				strBuf = new StringWriter(new StringBuilder(100000));
				xmlOut = new XmlTextWriter(strBuf);
				madeXmlOut = true;
			}
			xmlOut.WriteStartElement(name);

			XmlNodeList objs = m_state.list;
			if(objs != null && objs.Count > 0)
			{
				XmlBusinessObject obj = new XmlBusinessObject(m_bizobj.objType, null);
				for (int pos = 0; pos < objs.Count; ++pos)
				{
					obj.setElement((XmlElement)objs[pos]);
					obj.getXml(null, decoInfo, setOnly, dirtyOnly, newOnly, getBasic, getObjs, getILists, getSysVals, xmlOut);
				}
			}

			xmlOut.WriteEndElement();
			if(madeXmlOut)
			{
				xmlOut.Close();
				strBuf.Close();
				return strBuf.ToString();
			}
			return null;
		}
		
		public override IBizObj insertNew()
		{
			IBizObj newObj = null;
			XmlElement newEl = null;
			int numEl = numElements;
			string newElName = m_state.objNodeName();
			if(newElName == null || newElName.Length == 0)
				newElName = m_bizobj.type.Name;

			if (numEl > 0)
			{
				XmlElement curEl = (XmlElement)m_state.list[numEl-1];
				newEl = (XmlElement)curEl.ParentNode.AppendChild(curEl.OwnerDocument.CreateElement(newElName));
			}
			else if (m_state.InsertIntoBase)
			{
				XmlElement baseEl = m_state.getForceBaseEl();
				newEl = (XmlElement)m_state.BaseEl.AppendChild(baseEl.OwnerDocument.CreateElement(newElName));
			}
			if (newEl != null)
				newObj = new XmlBusinessObject(m_bizobj.objType, newEl);
			newObj.isNew=true;
			return newObj;
		}
		
		public override IBizObj insertNewMakeCopy(IBizObj obj)
		{
			//TODO: Implement this properly
			return insertNew();
		}
		
		public override void  refresh()
		{
			m_state.refresh();
		}
		
		public override string ToString()
		{
			return Xml;
		}		
		protected IBizObj getElementAtIndex(int pos)
		{
			if (pos >= 0 && pos < numElements)
				return new XmlBusinessObject(this.objectType, (XmlElement)m_state.list[pos]);
			else
				return null;
		}

		public override object Clone()
		{
			return null;
		}

		public override IBizObjCursor createCursor()
		{
			return new XmlBizObjCursor(this);
		}

		public override void removeAt(int index)
		{

		}

		public override IBizObj this[int index]
		{
			get
			{
				if (index >= 0 && index < numElements)
					return new XmlBusinessObject(this.objectType, (XmlElement)m_state.list[index]);
				else
					return null;
			}
			set
			{
			}
		}
		public override void Clear()
		{
			//TODO:  Implement Clear Method.
		}

	}
}